﻿using System;
using System.Web;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Security;
using System.Web.Script.Serialization;
using System.Linq;

using MvcCms.Data;
using MvcCms.Service.Filters;
using MvcCms.Service.Code.Email;
using MvcCms.Service;
using MvcCms.Store.Web.ViewModels;
using MvcCms.Data.Entities;
using MvcCms.Service.Code.Encryption;
using MvcCms.Service.Code;

using MvcCms.Store.Service;
using AutoMapper;
using MvcCms.Service.Logging;
using MvcCms.Store.ViewModels;
using System.IO;
using MvcCms.Service.Cache;

namespace MvcCms.Store.Web.Controllers
{
    [RequireSsl(Redirect = true)]
    [Authorize(Roles = "Admin")]
    public class StoreManagerController : MvcCms.Service.Code.BaseClasses.CMSControllerBase
    {
        #region Constructors
        private readonly IStoreService _storeService;
        private readonly ICacheService _cacheService;
        private readonly IAccountService _accountService;
        public StoreManagerController(ICacheService cacheService, IStoreService storeService, IAccountService accountService, IZoneService zoneService, ICmsService cmsService)
            : base(cmsService, zoneService, accountService)
        {
            _storeService = storeService;
            _cacheService = cacheService;
            _accountService = accountService;
        }

        #endregion

        public JsonResult DeleteImage(string imageName, int portalId)
        {
            try
            {
                var foldername = _cacheService.GetCurrentPortal().URLAuthority;
                string path = Server.MapPath("~/Uploadedimages/" + foldername);

                string filePath = Path.Combine(path, Path.GetFileName(imageName));
                if (System.IO.File.Exists(filePath) == true)
                {
                    System.IO.File.Delete(filePath);
                    string thumbPath = Path.Combine(path + "\\thumbs", Path.GetFileName(imageName));
                    if (System.IO.File.Exists(thumbPath) == true)
                    {
                        System.IO.File.Delete(thumbPath);
                        return Json(new { result = "success" });
                    }
                    return Json(new { result = "The thumbnail could not be found." });
                }
                else
                {
                    return Json(new { error = "File doesnot exist" });
                }
            }
            catch (UnauthorizedAccessException ex)
            {
                return Json(new { error = "You do not have required permission for this operation " + ex.Message });
            }
            catch (IOException exIO)
            {
                return Json(new { error = "File in use " + exIO.Message });
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }

        public ActionResult ImageManager()
        {
            string foldername = _cacheService.GetCurrentPortal().URLAuthority;

            string path = Server.MapPath("~/Uploadedimages/" + foldername);
            string thumbpath = Server.MapPath("~/Uploadedimages/" + foldername + "/thumbs");

            Directory.CreateDirectory(path);
            Directory.CreateDirectory(thumbpath);
            var di = new DirectoryInfo(thumbpath);
            FileInfo[] rgFiles = di.GetFiles("*.*");
            var model = new DefaultViewModel
            {
                _Portal = _cacheService.GetCurrentPortal(),
                _Files = rgFiles
            };
            ViewBag.Title = "Image Manager";
            return View(model);
        }

        [HttpPost]
        public ActionResult ImageManager(FormCollection forms)
        {
            ViewBag.Message = "";
            string foldername = _cacheService.GetCurrentPortal().URLAuthority;

            string path = Server.MapPath("~/Uploadedimages/" + foldername);

            foreach (string inputTagName in Request.Files)
            {
                HttpPostedFileBase file = Request.Files[inputTagName];

                if (file.ContentLength > 0)
                {
                    string filePath = Path.Combine(path, Path.GetFileName(file.FileName));
                    string thumbPath = Path.Combine(path + "\\thumbs", Path.GetFileName(file.FileName));
                    if (file.FileName.Contains("jpg") ||
                        file.FileName.Contains("gif") ||
                        file.FileName.Contains("png"))
                    {
                        file.SaveAs(filePath);
                        Files.ResizeImage(filePath, filePath, 450, 900, true);                        
                        Files.ResizeImage(filePath, thumbPath, 150, 300, false);
                    }
                }
            }

            var di = new DirectoryInfo(path);
            FileInfo[] rgFiles = di.GetFiles("*.*");
            var model = new DefaultViewModel
            {
                _Portal = _cacheService.GetCurrentPortal(),
                _Files = rgFiles
            };
            ViewBag.Title = "Image Manager";
            return View(model);
        }

        public ActionResult DailyStoreOrders()
        {
            var portal = _cacheService.GetCurrentPortal();

            var model = new DefaultViewModel
            {
                _Portal = portal
            };
            ViewBag.Title = portal.Name;
            return View(model);
        }

        [HttpPost]
        public ActionResult StoreOrders(int portalId, DateTime dateToGetOrdersFor)
        {
            var orders = _storeService.ListOrders(portalId, dateToGetOrdersFor);

            var ordersViewModel = new List<OrderViewModel>();
            foreach (var order in orders)
            {
                Mapper.CreateMap<StoreOrder, OrderViewModel>();
                var orderViewModel = Mapper.Map<StoreOrder, OrderViewModel>(order);
                ordersViewModel.Add(orderViewModel);
            }

            return PartialView(ordersViewModel);
        }

        public JsonResult ToggelPriceOption(int priceOptionID, bool on, int productId)
        {
            try
            {
                var product = _storeService.GetProduct(productId);
                var priceOption = _storeService.GetPriceOption(priceOptionID);

                if (on)
                {
                    product.PricingOptions.Add(priceOption);
                }
                else
                {
                    product.PricingOptions.Remove(priceOption);
                }

                if (_storeService.EditProduct(product))
                {                    
                    return Json(new { success = true });
                }
                return Json(new { error = "There was a problem saving the price option setting." });
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }

        public ViewResult PriceOptions()
        {
            var portal = _cacheService.GetCurrentPortal();
            var user = _accountService.GetUser();
            SecurityCheck(portal, user);

            var priceOptions = _storeService.ListPriceOptions(portal.PortalID);

            var model = new DefaultViewModel
            {
                _Portal = portal,
                _PriceOptions = priceOptions
            };
            ViewBag.Title = "Manager";
            return View(model);
        }

        public ViewResult Index()
        {
            var portal = _cacheService.GetCurrentPortal();
            var user = _accountService.GetUser();
            SecurityCheck(portal, user);

            var products = _storeService.ListActiveProductsWithCategory(portal.PortalID);

            var model = new DefaultViewModel
            {
                _Portal = portal,
                _Products = products
            };
            ViewBag.Title = "Manager";
            return View(model);
        }

        public ViewResult Details(int id)
        {
            var portal = _cacheService.GetCurrentPortal();
            var user = _accountService.GetUser();
            SecurityCheck(portal, user);

            var product = _storeService.GetProduct(id);

            Mapper.CreateMap<StoreProduct, ProductViewModel>();
            var productModel = Mapper.Map<StoreProduct, ProductViewModel>(product);

            var model = new DefaultViewModel
            {
                _Portal = portal,
                _Product = productModel
            };
            ViewBag.Title = "Product Details";
            return View(model);
        }

        public ActionResult CreatePriceOption()
        {
            var portal = _cacheService.GetCurrentPortal();
            var user = _accountService.GetUser();
            SecurityCheck(portal, user);

            var categories = _storeService.ListPriceOptions(portal.PortalID);

            var model = new DefaultViewModel
            {
                _Portal = portal
            };
            ViewBag.Title = "Create Price Option";
            return View(model);
        }

        [HttpPost]
        public ActionResult CreatePriceOption([Bind(Prefix = "_PriceOption")] PriceOptionViewModel createdPriceOption)
        {
            var portal = _cacheService.GetCurrentPortal();
            var user = _accountService.GetUser();
            SecurityCheck(portal, user);

            if (ModelState.IsValid)
            {
                Mapper.CreateMap<PriceOptionViewModel, StorePricingOption>();
                var priceOptionToCreate = Mapper.Map<PriceOptionViewModel, StorePricingOption>(createdPriceOption);

                priceOptionToCreate.PortalID = portal.PortalID;
                if (_storeService.CreatePriceOption(priceOptionToCreate))
                {
                    return RedirectToAction("PriceOptions");
                }
            }

            var model = new DefaultViewModel
            {
                _PriceOption = createdPriceOption,
                _Portal = portal
            };
            ViewBag.Title = "Create Price Option";
            return View(model);
        }

        public ActionResult Create()
        {
            var portal = _cacheService.GetCurrentPortal();
            var user = _accountService.GetUser();
            SecurityCheck(portal, user);

            var categories = _storeService.ListCategories(portal.PortalID);
            ViewData["_Product.CategoryID"] = new SelectList(categories, "CategoryID", "Name");

            var model = new DefaultViewModel
            {
                _Portal = portal
            };
            ViewBag.Title = "Create Product";
            return View(model);
        }

        [HttpPost]
        public ActionResult Create([Bind(Prefix = "_Product")] ProductViewModel createdProduct)
        {
            var portal = _cacheService.GetCurrentPortal();
            var user = _accountService.GetUser();
            SecurityCheck(portal, user);

            if (ModelState.IsValid)
            {
                Mapper.CreateMap<ProductViewModel, StoreProduct>();
                var productToCreate = Mapper.Map<ProductViewModel, StoreProduct>(createdProduct);

                productToCreate.CreatedBy = _accountService.GetUser().UserID;
                productToCreate.Active = true;
                productToCreate.PortalID = portal.PortalID;
                if (_storeService.CreateProduct(productToCreate))
                {
                    return RedirectToAction("Index");
                }
            }            

            var categories = _storeService.ListCategories(portal.PortalID);
            ViewData["_Product.CategoryID"] = new SelectList(categories, "CategoryID", "Name");

            var model = new DefaultViewModel
            {
                _Product = createdProduct,
                _Portal = portal
            };
            ViewBag.Title = "Create Product";
            return View(model);
        }

        public ActionResult EditPriceOption(int id)
        {
            var portal = _cacheService.GetCurrentPortal();
            var user = _accountService.GetUser();
            SecurityCheck(portal, user);

            var product = _storeService.GetPriceOption(id);

            Mapper.CreateMap<StorePricingOption, PriceOptionViewModel>();
            var priceOptionViewModel = Mapper.Map<StorePricingOption, PriceOptionViewModel>(product);

            var model = new DefaultViewModel
            {
                _Portal = portal,
                _PriceOption = priceOptionViewModel
            };
            ViewBag.Title = "Edit Price Option";
            return View(model);
        }

        [HttpPost]
        public ActionResult EditPriceOption([Bind(Prefix = "_PriceOption")] PriceOptionViewModel editedPriceOption)
        {
            var portal = _cacheService.GetCurrentPortal();
            var user = _accountService.GetUser();
            SecurityCheck(portal, user);

            if (ModelState.IsValid)
            {
                var priceOptionToEdit = _storeService.GetPriceOption(editedPriceOption.PriceOptionID);

                priceOptionToEdit.Description = editedPriceOption.Description;
                priceOptionToEdit.Price = editedPriceOption.Price;
                priceOptionToEdit.Title = editedPriceOption.Title;
                priceOptionToEdit.RequiresNotes = editedPriceOption.RequiresNotes;
                priceOptionToEdit.NotesInstructions = editedPriceOption.NotesInstructions;

                if (_storeService.EditPriceOption(priceOptionToEdit))
                {
                    return RedirectToAction("PriceOptions");
                }
            }

            var model = new DefaultViewModel
            {
                _Portal = portal,
                _PriceOption = editedPriceOption
            };
            ViewBag.Title = "Edit Price Option";
            return View(model);
        }

        public ActionResult Edit(int id)
        {
            var portal = _cacheService.GetCurrentPortal();
            var user = _accountService.GetUser();
            SecurityCheck(portal, user);

            var product = _storeService.GetProduct(id);

            var categories = _storeService.ListCategories(portal.PortalID);
            ViewData["_Product.CategoryID"] = new SelectList(categories, "CategoryID", "Name", product.CategoryID);
            var priceOptions = _storeService.ListPriceOptions(portal.PortalID);

            Mapper.CreateMap<StoreProduct, ProductViewModel>();
            var productModel = Mapper.Map<StoreProduct, ProductViewModel>(product);

            string foldername = portal.URLAuthority;
            string imagesPath = Server.MapPath("~/Uploadedimages/" + foldername);
            var di = new DirectoryInfo(imagesPath);
            FileInfo[] images = di.GetFiles("*.*");
            ViewData["_Product.ProductArtUrl"] = new SelectList(images, "Name", "Name", product.ProductArtUrl);

            var model = new DefaultViewModel
            {
                _Portal = portal,
                _Product = productModel,
                _PriceOptions = priceOptions
            };
            ViewBag.Title = "Edit Product";
            return View(model);
        }

        [HttpPost]
        public ActionResult Edit([Bind(Prefix = "_Product")] ProductViewModel editedProduct)
        {
            var portal = _cacheService.GetCurrentPortal();
            var user = _accountService.GetUser();
            SecurityCheck(portal, user);

            if (ModelState.IsValid)
            {
                var productToEdit = _storeService.GetProduct(editedProduct.ProductID);

                productToEdit.Title = editedProduct.Title;
                productToEdit.Description = editedProduct.Description;
                productToEdit.Active = editedProduct.Active;
                productToEdit.Price = editedProduct.Price;
                productToEdit.CategoryID = editedProduct.CategoryID;
                productToEdit.ProductArtUrl = editedProduct.ProductArtUrl;

                if (_storeService.EditProduct(productToEdit))
                {
                    return RedirectToAction("Index");
                }
            }

            var categories = _storeService.ListCategories(portal.PortalID);
            ViewData["_Product.CategoryID"] = new SelectList(categories, "CategoryID", "Name", editedProduct.CategoryID);
            var priceOptions = _storeService.ListPriceOptions(portal.PortalID);

            string foldername = portal.URLAuthority;
            string imagesPath = Server.MapPath("~/Uploadedimages/" + foldername);
            var di = new DirectoryInfo(imagesPath);
            FileInfo[] images = di.GetFiles("*.*");
            ViewData["_Product.ProductArtUrl"] = new SelectList(images, "Name", "Name", editedProduct.ProductArtUrl);

            var model = new DefaultViewModel
            {
                _Portal = portal,
                _Product = editedProduct,
                _PriceOptions = priceOptions
            };
            ViewBag.Title = "Edit Product";
            return View(model);
        }

        private ActionResult SecurityCheck(Portal portal, User user)
        {
            if (!Roles.IsUserInRole("StoreAdmin"))
            {
                if (user.PortalID!=0)
                {
                    if (portal.PortalID != user.PortalID)
                    {
                        //kick them out
                        return Redirect("http://www.mvccms.net");
                    }
                }
                else
                {
                    //kick them out
                    return Redirect("http://www.mvccms.net");
                }
            }
            return null;
        }

    }
}